package org.cid54.jshopper.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cid54.jshopper.dao.ItemDao;
import org.cid54.jshopper.dao.ShopItemDao;
import org.cid54.jshopper.dao.ShoppingListDao;
import org.cid54.jshopper.dao.UserDao;
import org.cid54.jshopper.dao.UserGroupDao;
import org.cid54.jshopper.model.Item;
import org.cid54.jshopper.model.ShopItem;
import org.cid54.jshopper.model.ShoppingList;
import org.cid54.jshopper.model.User;
import org.cid54.jshopper.model.UserGroup;
import org.cid54.jshopper.service.AdminService;
import org.cid54.jshopper.util.Hashher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author fgo
 */
@Service
@Transactional
public class AdminServiceImpl implements AdminService {

    @Autowired
    private Hashher hashher;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserGroupDao userGroupDao;
    @Autowired
    private ItemDao itemDao;
    @Autowired
    private ShopItemDao shopItemDao;
    @Autowired
    private ShoppingListDao shoppingListDao;

    @Override
    public List<User> getAllUsers() {
        return this.userDao.getAll();
    }

    @Override
    public List<UserGroup> getAllGroups() {
        return this.userGroupDao.getAll();
    }

    @Override
    public List<Item> getAllItems() {
        return this.itemDao.getAll();
    }

    public Map<User, Map<UserGroup, Boolean>> getUsersMemberShips() {

        List<UserGroup> userGroups = this.getAllGroups();

        Map<User, Map<UserGroup, Boolean>> resultM = new HashMap<User, Map<UserGroup, Boolean>>();

        for (User u : this.getAllUsers()) {

            resultM.put(u, new HashMap<UserGroup, Boolean>());

            for (UserGroup ug : userGroups) {

                resultM.get(u).put(ug, u.getUserGroups().contains(ug));

            }

        }

        return resultM;

    }

    @Override
    public void updateItem(long itemId, String name) {

        Item item = this.itemDao.findById(itemId);

        item.setName(name);

        this.itemDao.update(item);

    }

    @Override
    public void createItem(String name) {

        Item item = new Item();

        item.setName(name);

        this.itemDao.create(item);

    }

    @Override
    public void deleteItem(long itemId) {

        Item item = this.itemDao.findById(itemId);

        //Delete the dependencies
        for (ShopItem shopItem : this.shopItemDao.findByItem(item)) {
            this.shopItemDao.delete(shopItem);
        }

        this.itemDao.delete(item);

    }

    @Override
    public void updateUser(long userId, User user, List<Long> userGroupIds) {

        User dbUser = this.userDao.findById(userId);

        dbUser.setName(user.getName());
        dbUser.setAdmin(user.isAdmin());
        if (user.getPassword() != null && user.getPassword().trim().length() > 0) {

            String passwd = this.hashher.getHash(user.getPassword(), dbUser.getSalt());

            dbUser.setPassword(passwd);
        }

        dbUser.getUserGroups().clear();

        for (Long userGroupId : userGroupIds) {

            dbUser.addUserGroup(this.userGroupDao.findById(userGroupId));

        }

        this.userDao.update(dbUser);

    }

    @Override
    public void createUser(User user, List<Long> userGroupIds) {

        user.setGuid(this.hashher.getNewGuid());

        user.setSalt(this.hashher.getRandomSalt());

        user.setPassword(this.hashher.getHash(user.getPassword(), user.getSalt()));

        for (Long userGroupId : userGroupIds) {

            user.addUserGroup(this.userGroupDao.findById(userGroupId));

        }

        this.userDao.create(user);

    }

    @Override
    public void deleteUser(long userId) {

        User u = this.userDao.findById(userId);

        this.userDao.delete(u);

    }

    @Override
    public void deleteGroup(long groupId) {
        UserGroup group = this.userGroupDao.findById(groupId);

        for (ShoppingList shoppingList : this.shoppingListDao.findByUserGroup(group)) {
            this.shoppingListDao.delete(shoppingList);
        }

        group.getUsers().clear();

        this.userGroupDao.update(group);

        this.userGroupDao.delete(group);
    }

    @Override
    public void createGroup(UserGroup group) {

        this.userGroupDao.create(group);

    }

    @Override
    public void updateGroup(long groupId, String groupName) {

        UserGroup group = this.userGroupDao.findById(groupId);

        group.setName(groupName);

        this.userGroupDao.update(group);

    }
}
